using System;

namespace Nice157Advices.Advices
{
    /// <summary>
    /// 62.避免嵌套异常
    /// </summary>
    public static class _62
    {

        public static void Go ()
        {
            var nes = new NestedExceptionSample ();
            try
            {
                nes.MethodWithTry ();
            }
            catch (Exception ex)
            {
                // 嵌套异常：
                // 在此异常输出中已经找不到原始错误（Method1的）位置了。
                // 需要做的是防止调用堆栈被重置：直接 throw 代替 throw err;
                // 请看第三个trycatch
                System.Console.WriteLine ("1: \t" + ex.StackTrace);
            }

            try
            {
                nes.MethodNoTry();
            }
            catch (Exception ex)
            {
                System.Console.WriteLine("2. \t" + ex.StackTrace);
            }

            try
            {
                nes.MethodWithTry2();
            }
            catch (System.Exception ex)
            {
                System.Console.WriteLine("3: \t" + ex.StackTrace);
            }
        }

        private class NestedExceptionSample
        {
            public void MethodWithTry ()
            {
                try
                {
                    (new NestedExceptionSample2 ()).MethodWithTry ();
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }

            public void MethodNoTry ()
            {
                (new NestedExceptionSample2 ()).MethodNoTry ();
            }

            public void MethodWithTry2() {
                try
                {
                    (new NestedExceptionSample2()).MethodNoTry();
                }
                catch (System.Exception)
                {
                    throw;
                }
            }

            private class NestedExceptionSample2
            {
                public void MethodWithTry ()
                {
                    try
                    {
                        Method1 ();
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }
                }

                public void MethodNoTry ()
                {
                    Method1 ();
                }

                private int Method1 ()
                {
                    int i = 0;
                    return 10 / i;
                }
            }
        }
    }
}